﻿using System;
using System.Linq;
using System.IO;
using System.IO.IsolatedStorage;
using System.Collections.Generic;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Framework.Client;
using Microsoft.LightSwitch.Presentation;
using Microsoft.LightSwitch.Presentation.Extensions;
namespace LightSwitchApplication
{
    public partial class RMA_RiepilogoMaterialeOrdine
    {
        public int GetNextNumber(int tipoDocumento)
        {
            var lastOrder = (from i in DataWorkspace.ApplicationData.Documenti.Where(d => d.TipoDocumento == tipoDocumento)
                             where i.Data.HasValue && i.Data.Value.Year == DateTime.Now.Year
                             orderby i.NumeroDocumento descending
                             select i).FirstOrDefault();

            if (lastOrder != null)
                return lastOrder.NumeroDocumento + 1;

            return 1;
        }

        partial void CreaOrdiniFornitore_Execute()
        {
            // Write your code here.
            Save();

            //Materiali da ordinare.
            var dett = RiepilogoMaterialeByOrdine.Where(r => r.Ordinare);

            if (dett.Count() == 0)
            {
                this.ShowMessageBox("Nessun elemento selezionato, selezionare voci da ordinare ", "Creazione Ordine Materiale", MessageBoxOption.Ok);

                return;
            }

            var rslt = this.ShowMessageBox("Saranno creati o aggiornati ordini fornitori per l'acquisto di " + dett.Count() +
                " voci materiale . \n Proseguire ?", "Conferma avanzamento ordini materiale", MessageBoxOption.OkCancel);

            if (rslt == System.Windows.MessageBoxResult.Cancel) return;

            this.Save();

            var vociAggiornate = 0;
            var ordiniCreati = 0;
            var vociCreate = 0;

            // Raggruppo i materiali per anagrafica
            var groups = from g in dett
                         group g by g.MaterialeGrezzo.Anagrafica
                             into ng
                             select ng;


            foreach (var g in groups)
            {
                var forn = g.Key; // fornitore , può essere null

                Documento ordine = null;
                if (forn != null)
                {
                    // Cerco eventuale ordine fornitore con stessa anagrafica, non emesso, ultimo in ordine di data 
                    ordine = DataWorkspace.ApplicationData.Documenti.
                                Where(d => d.TipoDocumento == (int)TipoDocumento.OrdiniFornitoreMateriale).
                                Where(f => f.Anagrafica.Id == forn.Id).
                                Where(f => !f.Emesso).
                                OrderByDescending(f => f.Data).Take(1).FirstOrDefault();
                }

                // Se ordine non esiste ne creo uno nuovo)
                if (ordine == null)
                {
                    ordine = DataWorkspace.ApplicationData.Documenti.AddNew();
                    ordine.Anagrafica = forn;
                    ordine.Data = DateTime.Now;
                    ordine.TipoDocumento = (int)TipoDocumento.OrdiniFornitoreMateriale;

                    ordine.NumeroDocumento = GetNextNumber((int)TipoDocumento.OrdiniFornitoreMateriale);

                    ordiniCreati++;

                    Save();
                }

                /*
                 * Per ogni fornitore:
                 * - Cerco ordine fornitore materiale in stato bozza.
                 *  - Se esiste controllo che ci sia voce per stesso materiale, e quindi aggiungo qta.
                 *          - se voce non esiste , la aggiungo
                 *          
                 *  - Se non esisteva ordine del fornitore lo creo e aggiungo voci..
                 */
                foreach (var dettaglioMaterialeDaOrdinare in g)
                {
                    /*
                     * Se in questo ordine esiste già stesso codice materiale e non è un taglio ,
                     * aggiungo quantita
                     */
                    if (TryInsertMaterial(dettaglioMaterialeDaOrdinare, ordine, ref vociAggiornate)) continue;

                    // se arrivo qui significa che devo aggiungere voce all'ordine.
                    var d = ordine.DettagliDocumentoMateriale.AddNew();

                    d.MaterialeGrezzo = dettaglioMaterialeDaOrdinare.MaterialeGrezzo;

                    d.TaglioInMisura = dettaglioMaterialeDaOrdinare.TaglioInMisura;

                    if (dettaglioMaterialeDaOrdinare.TaglioInMisura)
                    {
                        d.LunghezzaTaglio = dettaglioMaterialeDaOrdinare.LunghezzaTaglio;
                        d.NumeroPezzi = dettaglioMaterialeDaOrdinare.NumeroPezzi;
                    }

                    else
                    {
                        d.Totale = dettaglioMaterialeDaOrdinare.Totale;
                    }

                    // Aggiungere il riferimento anche ai vari dettagli ordine.
                    foreach (var dettRiepilogo in dettaglioMaterialeDaOrdinare.DettaglioRiepilogoMateriali)
                        d.DettagliDocumento.Add(dettRiepilogo.DettaglioDocumento);

                    vociCreate++;
                }
            }

            var operationMessage = string.Format(@"Operazione effettuta con successo !
                Ordini Creati : {0}
                Voci Aggiornate : {1}
                VociCreate : {2} ", ordiniCreati, vociAggiornate, vociCreate);

            this.ShowMessageBox(operationMessage, "Messaggio Operazione", MessageBoxOption.Ok);

            this.Save();

        }

        /// <summary>
        /// Cerca se in un'ordine posso inserire materiale.
        /// Il dettaglio non deve essere un taglio.
        /// </summary>
        /// <param name="dettaglioMaterialeDaOrdinare"></param>
        /// <param name="ordine"></param>
        /// <param name="vociAggiornate"></param>
        /// <returns></returns>
        private static bool TryInsertMaterial(RiepilogoMateriale dettaglioMaterialeDaOrdinare, Documento ordine, ref int vociAggiornate)
        {
            // Se il materiale è tagliato in misura non aggiorno l'eventuale voce.
            if (dettaglioMaterialeDaOrdinare.TaglioInMisura)
                return false;

            foreach (var d in ordine.DettagliDocumentoMateriale)
            {
                var mat = d.MaterialeGrezzo;

                var matToOrder = dettaglioMaterialeDaOrdinare.MaterialeGrezzo;

                if (mat == null || matToOrder == null) continue;

                if (mat.Id == matToOrder.Id && (!d.TaglioInMisura))
                {
                    // Trovato dettaglio da ordinare .

                    // Aggiungere il riferimento anche ai vari dettagli ordine.
                    foreach (var dettRiepilogo in dettaglioMaterialeDaOrdinare.DettaglioRiepilogoMateriali)
                        d.DettagliDocumento.Add(dettRiepilogo.DettaglioDocumento);

                    //se arriva qui il materiale viene aggiunto
                    if (!d.Totale.HasValue)
                        d.Totale = 0;

                    d.Totale += dettaglioMaterialeDaOrdinare.Totale;

                    vociAggiornate++;

                    return true;
                }
            }

            return false;

        }

        partial void StampaCmd_Execute()
        {
            // Write your code here.

            this.Application.ShowRPT_RiepilogoMaterialeOrdine(RiepilogoMaterialeOrdineId);

        }

        //partial void RMA_RiepilogoMaterialeOrdine_Saving(ref bool handled)
        //{
        //    handled = true;
        //    try
        //    {
        //        this.DataWorkspace.ApplicationData.SaveChanges();
        //    }
        //    catch (ConcurrencyException e)
        //    {
        //        foreach (IEntityObject entityConflict in e.EntitiesWithConflicts)
        //        {
        //            if (entityConflict is RiepilogoMateriale)
        //            {
        //                entityConflict.Details.EntityConflict.ResolveConflicts(Microsoft.LightSwitch.Details.ConflictResolution.ServerWins);
        //                this.DataWorkspace.ApplicationData.SaveChanges();
        //            }

        //            //EntityPropertyConflict statusProperty =
        //            //   entityConflict.Details.EntityConflict.ConflictingProperties.Where(
        //            //   property => property.Property.Name == "Status").Single();
        //            //if (statusProperty.Property.Value.ToString() == statusProperty.ServerValue.ToString())
        //            //{
        //            //    statusProperty.EntityConflict.ResolveConflicts(ConflictResolution.ClientWins);
        //            //    //Resave once we’ve resolved the conflicts
        //            //    this.DataWorkspace.ApplicationData.SaveChanges();
        //            //}
        //        }
        //    }

        //}


    }
}
